package com.petdog.module.tools.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.petdog.infrastructure.entity.BehaviorGuide;
import com.petdog.infrastructure.entity.BehaviorTag;
import com.petdog.infrastructure.entity.BehaviorWiki;
import com.petdog.infrastructure.entity.GuideTagRel;
import com.petdog.infrastructure.mapper.*;
import com.petdog.module.tools.dto.BehaviorGuideDTO;
import com.petdog.module.tools.dto.BehaviorWikiDTO;
import com.petdog.module.tools.dto.GetBehaviorGuidesRequest;
import com.petdog.module.tools.dto.SearchBehaviorGuideRequest;
import com.petdog.module.tools.service.BehaviorGuideService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BehaviorGuideServiceImpl implements BehaviorGuideService {

    @Autowired
    private BehaviorGuideMapper behaviorGuideMapper;
    
    @Autowired
    private BehaviorTagMapper behaviorTagMapper;
    
    @Autowired
    private GuideTagRelMapper guideTagRelMapper;
    
    @Autowired
    private BehaviorWikiMapper behaviorWikiMapper;
    
    @Autowired
    private UserGuideHistoryMapper userGuideHistoryMapper;
    
    @Autowired
    private HotSearchMapper hotSearchMapper;

    @Override
    public Page<BehaviorGuideDTO> getBehaviorGuides(GetBehaviorGuidesRequest request) {
        Page<BehaviorGuide> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LambdaQueryWrapper<BehaviorGuide> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BehaviorGuide::getStatus, 1); // 只查询已发布的
        
        if (StringUtils.hasText(request.getContentType())) {
            queryWrapper.eq(BehaviorGuide::getContentType, request.getContentType());
        }
        if (StringUtils.hasText(request.getDifficultyLevel())) {
            queryWrapper.eq(BehaviorGuide::getDifficultyLevel, request.getDifficultyLevel());
        }
        if (StringUtils.hasText(request.getPetType())) {
            queryWrapper.eq(BehaviorGuide::getPetType, request.getPetType());
        }
        
        // 根据标签筛选
        if (request.getTagId() != null) {
            List<Long> guideIds = guideTagRelMapper.selectGuideIdsByTagId(request.getTagId());
            if (guideIds != null && !guideIds.isEmpty()) {
                queryWrapper.in(BehaviorGuide::getGuideId, guideIds);
            } else {
                // 如果没有匹配的指南，返回空页
                return new Page<>();
            }
        }
        
        // 排序
        if (StringUtils.hasText(request.getOrderBy())) {
            if ("view_count".equals(request.getOrderBy())) {
                if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
                    queryWrapper.orderByAsc(BehaviorGuide::getViewCount);
                } else {
                    queryWrapper.orderByDesc(BehaviorGuide::getViewCount);
                }
            } else {
                // 默认按创建时间排序
                if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
                    queryWrapper.orderByAsc(BehaviorGuide::getCreateTime);
                } else {
                    queryWrapper.orderByDesc(BehaviorGuide::getCreateTime);
                }
            }
        } else {
            // 默认按创建时间降序排序
            queryWrapper.orderByDesc(BehaviorGuide::getCreateTime);
        }
        
        Page<BehaviorGuide> resultPage = behaviorGuideMapper.selectPage(page, queryWrapper);
        return convertToDTO(resultPage);
    }

    @Override
    public BehaviorGuideDTO getBehaviorGuideDetail(Long guideId) {
        BehaviorGuide guide = behaviorGuideMapper.selectById(guideId);
        if (guide == null || guide.getStatus() != 1) {
            return null;
        }
        
        // 增加浏览次数
        guide.setViewCount(guide.getViewCount() + 1);
        behaviorGuideMapper.updateById(guide);
        
        // 获取标签
        List<Long> tagIds = guideTagRelMapper.selectTagIdsByGuideId(guideId);
        List<String> tags = new ArrayList<>();
        if (tagIds != null && !tagIds.isEmpty()) {
            tags = behaviorTagMapper.selectBatchIds(tagIds).stream()
                    .map(BehaviorTag::getTagName)
                    .collect(Collectors.toList());
        }
        
        BehaviorGuideDTO dto = new BehaviorGuideDTO();
        BeanUtils.copyProperties(guide, dto);
        dto.setTags(tags);
        return dto;
    }

    @Override
    public Page<BehaviorGuideDTO> searchBehaviorGuides(SearchBehaviorGuideRequest request) {
        // 记录搜索关键词
        if (StringUtils.hasText(request.getKeyword())) {
            hotSearchMapper.incrementSearchCount(request.getKeyword());
        }
        
        Page<BehaviorGuide> page = new Page<>(request.getPageNum(), request.getPageSize());
        List<BehaviorGuide> guides = behaviorGuideMapper.searchByKeyword(request.getKeyword());
        
        // 过滤已发布的指南
        guides = guides.stream()
                .filter(guide -> guide.getStatus() == 1)
                .collect(Collectors.toList());
        
        // 应用其他筛选条件
        if (StringUtils.hasText(request.getContentType())) {
            guides = guides.stream()
                    .filter(guide -> request.getContentType().equals(guide.getContentType()))
                    .collect(Collectors.toList());
        }
        if (StringUtils.hasText(request.getDifficultyLevel())) {
            guides = guides.stream()
                    .filter(guide -> request.getDifficultyLevel().equals(guide.getDifficultyLevel()))
                    .collect(Collectors.toList());
        }
        if (StringUtils.hasText(request.getPetType())) {
            guides = guides.stream()
                    .filter(guide -> request.getPetType().equals(guide.getPetType()))
                    .collect(Collectors.toList());
        }
        
        // 分页
        int start = (request.getPageNum() - 1) * request.getPageSize();
        int end = Math.min(start + request.getPageSize(), guides.size());
        List<BehaviorGuide> pageContent = start < guides.size() ? guides.subList(start, end) : new ArrayList<>();
        
        page.setRecords(pageContent);
        page.setTotal(guides.size());
        
        return convertToDTO(page);
    }

    @Override
    public List<BehaviorTag> getAllTags() {
        return behaviorTagMapper.selectList(null);
    }

    @Override
    public List<BehaviorGuideDTO> getHotGuides(Integer limit) {
        List<BehaviorGuide> guides = behaviorGuideMapper.selectHotGuides(limit);
        return convertToDTOList(guides);
    }

    @Override
    public List<BehaviorGuideDTO> getRecommendGuides(Long userId, Integer limit) {
        // 优先从推荐算法获取，如果没有则返回热门指南
        List<BehaviorGuide> recommendGuides = behaviorGuideMapper.selectRecommendByUserId(userId, limit);
        if (recommendGuides == null || recommendGuides.isEmpty()) {
            recommendGuides = behaviorGuideMapper.selectHotGuides(limit);
        }
        return convertToDTOList(recommendGuides);
    }

    @Override
    public BehaviorWikiDTO getBehaviorWiki(String behaviorName) {
        BehaviorWiki wiki = behaviorWikiMapper.selectByBehaviorName(behaviorName);
        if (wiki == null || wiki.getStatus() != 1) {
            return null;
        }
        
        // 增加浏览次数
        wiki.setViewCount(wiki.getViewCount() + 1);
        behaviorWikiMapper.updateById(wiki);
        
        BehaviorWikiDTO dto = new BehaviorWikiDTO();
        BeanUtils.copyProperties(wiki, dto);
        return dto;
    }

    @Override
    public List<String> getSearchSuggestions(String prefix, Integer limit) {
        if (!StringUtils.hasText(prefix)) {
            return new ArrayList<>();
        }
        return hotSearchMapper.selectSuggestionsByPrefix(prefix, limit);
    }

    @Override
    public void recordUserHistory(Long userId, Long guideId) {
        userGuideHistoryMapper.insertHistory(userId, guideId);
    }

    @Override
    public void updateViewDuration(Long userId, Long guideId, Integer duration) {
        userGuideHistoryMapper.updateDuration(userId, guideId, duration);
    }

    // 辅助方法：将Page<BehaviorGuide>转换为Page<BehaviorGuideDTO>
    private Page<BehaviorGuideDTO> convertToDTO(Page<BehaviorGuide> page) {
        Page<BehaviorGuideDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(page, dtoPage);
        dtoPage.setRecords(convertToDTOList(page.getRecords()));
        return dtoPage;
    }

    // 辅助方法：将List<BehaviorGuide>转换为List<BehaviorGuideDTO>
    private List<BehaviorGuideDTO> convertToDTOList(List<BehaviorGuide> guides) {
        if (guides == null || guides.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取所有指南ID
        List<Long> guideIds = guides.stream().map(BehaviorGuide::getGuideId).collect(Collectors.toList());
        
        // 获取所有标签关联
        List<GuideTagRel> rels = guideTagRelMapper.selectList(new LambdaQueryWrapper<GuideTagRel>().in(GuideTagRel::getGuideId, guideIds));
        
        // 获取所有标签
        Set<Long> tagIds = rels.stream().map(GuideTagRel::getTagId).collect(Collectors.toSet());
        List<BehaviorTag> tags = behaviorTagMapper.selectBatchIds(tagIds);
        Map<Long, String> tagMap = tags.stream().collect(Collectors.toMap(BehaviorTag::getTagId, BehaviorTag::getTagName));
        
        // 构建指南-标签映射
        Map<Long, List<String>> guideTagMap = new HashMap<>();
        for (GuideTagRel rel : rels) {
            guideTagMap.computeIfAbsent(rel.getGuideId(), k -> new ArrayList<>())
                    .add(tagMap.get(rel.getTagId()));
        }
        
        // 转换为DTO
        return guides.stream().map(guide -> {
            BehaviorGuideDTO dto = new BehaviorGuideDTO();
            BeanUtils.copyProperties(guide, dto);
            dto.setTags(guideTagMap.getOrDefault(guide.getGuideId(), new ArrayList<>()));
            return dto;
        }).collect(Collectors.toList());
    }


}